#include "rcc_apb_periph.h"
#include "nvic.h"


sj_void periph_clock_config(struct rcc_apb_periph *apb)
{
    if(apb->apb==1)
    {
        SET_BIT(RCC->APB1ENR, (0x01<<apb->apb_offset));
    }
    else if(apb->apb==2)
    {
        SET_BIT(RCC->APB2ENR, (0x01<<apb->apb_offset));
    }
}

sj_void peripheral_timer_init(struct peripheral_timer *timer)
{
    TIM_HandleTypeDef *handler =&(nvic_get_tim_handler(timer->id)->tim_hander);

    handler->Instance=timer->base;
    handler->Init.Prescaler=timer->prescaler;
    handler->Init.CounterMode=timer->mode;
    handler->Init.Period=timer->period;
    handler->Init.ClockDivision=timer->division;
    HAL_TIM_Base_Init(handler);

    HAL_TIM_Base_Start_IT(handler);

    nvic_get_tim_handler(timer->id)->init=1;
}


sj_void peripheral_nvic_init(struct peripheral_nvic *nvic)
{

    HAL_NVIC_SetPriority(nvic->irq_num,nvic->preempt_priority,nvic->sub_priority);
    HAL_NVIC_EnableIRQ(nvic->irq_num);
}

extern sj_uint8 reciever_temp[1];
extern sj_uint8 reve_buff[256];
sj_void peripheral_usart_init(struct peripheral_usart *usart)
{
    UART_HandleTypeDef *handler =&(nvic_get_usart_handler(usart->id)->usart_hander);
    handler->Instance =usart->base;
    handler->Init.BaudRate=usart->bound;
    handler->Init.WordLength=usart->world_len;
    handler->Init.StopBits=usart->stop_n;
    handler->Init.Parity=usart->parity;
    handler->Init.Mode=usart->mode;
    handler->Init.HwFlowCtl=UART_HWCONTROL_NONE;
    handler->Init.OverSampling=UART_OVERSAMPLING_16;
    HAL_UART_Init(handler);
    nvic_get_usart_handler(usart->id)->init=1;
    nvic_get_usart_handler(usart->id)->ptr=usart;

    HAL_UART_Receive_IT(handler, reve_buff, 1);
}

sj_void peripheral_exit_init(sj_int8 id)
{
    EXTI_HandleTypeDef *handler =&(nvic_get_exti_handler(id)->exti_hander);

    handler->Line=id;
    handler->PendingCallback=NULL;

    nvic_get_exti_handler(id)->init=1;
}

sj_void peripheral_rtc_clock_config(struct rcc_lse_periph *rtc_lse)
{

    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = rtc_lse->oscillator_type;
    RCC_OscInitStruct.LSEState = rtc_lse->lse_state;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
      Error_Handler1();
    }

    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    PeriphClkInit.PeriphClockSelection = rtc_lse->periph_clock_selection;
    PeriphClkInit.RTCClockSelection = rtc_lse->rtc_cloc_selection;
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

    return 0;
}

sj_void peripheral_rtc_init(struct peripheral_rtc *hrtc1)
{
    RTC_TimeTypeDef stime = {0};
    RTC_DateTypeDef date_update = {0};

    RTC_HandleTypeDef *handler = &(nvic_get_rtc_handler(0)->rtc_hander);

    handler->Instance = (RTC_TypeDef *)hrtc1->instance;
    handler->Init.AsynchPrediv = hrtc1->asynchPrediv;
    handler->Init.OutPut = hrtc1->output;
    HAL_RTC_Init(handler);

    SET_BIT(handler->Instance->CRH, 0x1); //slj add for second interrupt

    stime.Hours = 0x16;
    stime.Minutes = 0x57;
    stime.Seconds = 0x0;
    HAL_RTC_SetTime(handler, &stime, RTC_FORMAT_BCD);

    date_update.WeekDay = RTC_WEEKDAY_TUESDAY;
    date_update.Month = RTC_MONTH_DECEMBER;
    date_update.Date = 0x28;
    date_update.Year = 0x21;
    HAL_RTC_SetDate(handler, &date_update, RTC_FORMAT_BCD);

    HAL_PWR_EnableBkUpAccess();  // for set nvic
    /* Enable BKP CLK enable for backup registers */
    __HAL_RCC_BKP_CLK_ENABLE();
    /* Peripheral clock enable */
    __HAL_RCC_RTC_ENABLE();
}

sj_void peripheral_rtc_get_time(struct rtc_date *data,struct rtc_time *time)
{
    RTC_HandleTypeDef *handler =&(nvic_get_rtc_handler(0)->rtc_hander);
    /* Get the RTC current Time */
    HAL_RTC_GetTime(handler, (RTC_TimeTypeDef*)time, RTC_FORMAT_BIN);
    /* Get the RTC current Date */
    HAL_RTC_GetDate(handler, (RTC_DateTypeDef*)data, RTC_FORMAT_BIN);

//    sj_kprintf("%02d/%02d/%02d\r\n",2000 + data->year, data->month, data->date);
//    sj_kprintf("%02d:%02d:%02d\r\n",time->hours, time->minutes, time->seconds);
//    sj_kprintf("week:%02d \r\n", data->weekDay);
//    sj_kprintf("\r\n");
}

sj_void peripheral_adc_clock_config(struct rcc_adc_periph_clk *adc_clk)
{

    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    PeriphClkInit.PeriphClockSelection = adc_clk->periph_clock_selection;
    PeriphClkInit.RTCClockSelection = adc_clk->adc_clock_selection;
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
    return 0;
}

sj_void peripheral_adc_init(struct peripheral_adc *hadc, struct peripheral_adc_channel *hadc_channel)
{
    ADC_HandleTypeDef *handler = &(nvic_get_adc_handler(0)->adc_handler);

    handler->Instance = (ADC_TypeDef *)hadc->base;
    handler->Init.ScanConvMode = hadc->scanconv_mode;
    handler->Init.ContinuousConvMode = hadc->continuousconv_mode;
    handler->Init.DiscontinuousConvMode = hadc->discontinuousconv_mode;
    handler->Init.ExternalTrigConv = hadc->external_trigconv;
    handler->Init.DataAlign = hadc->data_align;
    handler->Init.NbrOfConversion = hadc->nbrofconversion;
    HAL_ADC_Init(handler);

    ADC_ChannelConfTypeDef sConfig = {0};

    sConfig.Channel = hadc_channel->channel;
    sConfig.Rank = hadc_channel->rank;
    sConfig.SamplingTime = hadc_channel->samplingTime;
    if (HAL_ADC_ConfigChannel(handler, &sConfig) != HAL_OK)
    {
      Error_Handler();
    }
}

sj_uint16 peripheral_adc_start_get_data(struct peripheral_adc *hadc)
{
    ADC_HandleTypeDef *handler = &(nvic_get_adc_handler(0)->adc_handler);
    HAL_ADC_Start(handler);
    HAL_ADC_PollForConversion(handler, 50);
    sj_uint16 value = HAL_ADC_GetValue(handler);
    HAL_ADC_Stop(handler);
    return value;
}
